Skip to content

refactor(crud): update store to redux from reflux COMPASS-6844#8208

Open
Anemy wants to merge 9 commits into
mainfrom
COMPASS-6844-crud-redux
Open

refactor(crud): update store to redux from reflux COMPASS-6844#8208
Anemy wants to merge 9 commits into
mainfrom
COMPASS-6844-crud-redux

Conversation

@Anemy

@Anemy Anemy commented Jul 3, 2026

Copy link
Copy Markdown
Member

COMPASS-6844

This updates the base crud store to redux from reflux, and separates it out into a few reducers, insert, collection-meta, bulk-update, bulk-delete. This pr the does not update the grid-store, which is still in reflux.

Copilot AI review requested due to automatic review settings July 3, 2026 15:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the Compass CRUD plugin’s core store from Reflux to Redux (while explicitly keeping the grid store in Reflux for now), reshaping state management around reducer slices and wiring UI components to react-redux. Overall, the direction is sound for maintainability, but the scope is broad and there are a few correctness gaps that should be addressed before landing.

Changes:

  • Introduces a Redux root reducer for CRUD and splits state into slice reducers (documents, collection-meta, view, insert, bulk update/delete) with thunk-based side effects.
  • Updates CRUD UI components to use connect/Redux actions and introduces a React context bridge for the still-Reflux grid store.
  • Updates and adds tests to validate slice reducers and the Redux-backed plugin store behavior.

Reviewed changes

Copilot reviewed 37 out of 38 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/compass-crud/src/utils/parse-shell-bson.ts Adds shared BSON parsing helper for bulk update parsing.
packages/compass-crud/src/utils/is-action.ts Adds typed Redux action type guard helper.
packages/compass-crud/src/utils/fetch-documents.ts Adds fetch/findAndModify helpers used by Redux thunks.
packages/compass-crud/src/stores/view.ts Adds Redux slice for document view + table drilldown state.
packages/compass-crud/src/stores/reducer.ts Adds Redux root reducer + shared action/thunk typing.
packages/compass-crud/src/stores/insert.ts Adds Redux slice + thunks for insert dialog flows.
packages/compass-crud/src/stores/insert.spec.ts Adds reducer unit tests for insert slice behavior.
packages/compass-crud/src/stores/grid-store-context.ts Adds React context bridge for Reflux-backed grid store.
packages/compass-crud/src/stores/documents.ts Adds Redux slice + thunks for fetching/paging/editing documents and emitting events.
packages/compass-crud/src/stores/crud-store.spec.ts Refactors store tests to dispatch Redux actions/thunks and assert on Redux state.
packages/compass-crud/src/stores/collection-meta.ts Adds Redux slice for collection metadata/stats.
packages/compass-crud/src/stores/bulk-update.ts Adds Redux slice + thunks for bulk update modal + preview + execution toasts.
packages/compass-crud/src/stores/bulk-delete.ts Adds Redux slice + thunk for bulk delete confirmation + execution toasts/events.
packages/compass-crud/src/plugin-title.tsx Converts tab title header to connect to read collection stats from Redux.
packages/compass-crud/src/index.ts Updates plugin provider to supply grid store via context; switches header/content to Redux-connected components.
packages/compass-crud/src/components/table-view/full-width-cell-renderer.tsx Adjusts prop types away from legacy CrudActions signatures.
packages/compass-crud/src/components/table-view/document-table-view.tsx Subscribes to grid store via context instead of passing the whole crud store.
packages/compass-crud/src/components/table-view/document-table-view.spec.tsx Minor test typing cleanup.
packages/compass-crud/src/components/table-view/cell-renderer.tsx Adjusts prop typing for drilldown callback signature.
packages/compass-crud/src/components/table-view/cell-editor.tsx Adjusts prop typing and removes unnecessary RowNode casts.
packages/compass-crud/src/components/table-view/cell-editor.spec.tsx Minor test typing cleanup.
packages/compass-crud/src/components/json-editor.tsx Updates action prop types for Redux-dispatched functions.
packages/compass-crud/src/components/insert-document-dialog.tsx Converts insert dialog to a connected component using Redux slice actions/thunks.
packages/compass-crud/src/components/insert-document-dialog.spec.tsx Refactors tests to render dialog under a real activated Redux store.
packages/compass-crud/src/components/editable-document.tsx Updates action prop types away from legacy CrudActions signatures.
packages/compass-crud/src/components/document-list.tsx Converts main view to connect, dispatching Redux thunks; injects grid actions via context.
packages/compass-crud/src/components/crud-toolbar.tsx Updates prop types for Redux-backed state (nullable count, numeric resultId).
packages/compass-crud/src/components/change-view/change-view.tsx Small TS casting cleanup in change-view components.
packages/compass-crud/src/components/bulk-update-modal.tsx Converts bulk update modal to connected wrapper and derives filter from query bar hook.
packages/compass-crud/src/components/bulk-update-modal.spec.tsx Updates tests to import the unconnected modal component.
packages/compass-crud/src/components/bulk-delete-modal.tsx Converts bulk delete modal to connected wrapper and derives filter from query bar hook.
packages/compass-crud/src/components/bulk-delete-modal.spec.tsx Updates tests to import the unconnected modal component.
packages/compass-crud/src/actions/index.ts Scopes Reflux actions down to grid-store-only actions.
packages/compass-crud/README.md Removes outdated examples referencing Reflux CRUD actions.
packages/compass-crud/package.json Removes reflux-state-mixin; adds redux/react-redux/redux-thunk dependencies.
packages/compass-collection/src/modules/collection-tab.ts Adds isMockDataGeneratorEnabled metadata field used by CRUD options typing.
package-lock.json Updates lockfile for dependency changes.

Comment thread packages/compass-crud/src/stores/documents.ts Outdated
Comment thread packages/compass-crud/src/stores/documents.ts Outdated
Comment thread packages/compass-crud/src/stores/documents.ts
Comment thread packages/compass-crud/src/stores/insert.ts Outdated
Comment thread packages/compass-crud/src/stores/bulk-delete.ts Outdated
Comment thread packages/compass-crud/src/components/document-list.tsx Outdated

@gribnoysup gribnoysup left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do folks feel about having the grid store in another pr? Should we just do all of it at once?

I honestly feel like we should do this another way around and start from leaf stores, carefully evaluating the changes and what needs to be in their own slices (maybe their own stores / plugins) and how it is shaped, and only then move to the main crud store.

I left a few smaller comments based on a few first smaller store files, but the general problem with moving the current state and actions shape 1 to 1 from reflux to redux is that we are just inheriting all the current anti patterns of how this is done in a slightly different tech and I don't think this is moving us into the right direction

Comment thread packages/compass-collection/src/modules/collection-tab.ts Outdated
Comment on lines +26 to +30
export const BulkDeleteActionTypes = {
OPEN_DIALOG: 'crud/bulk-delete/OPEN_DIALOG',
CLOSE_DIALOG: 'crud/bulk-delete/CLOSE_DIALOG',
IN_PROGRESS: 'crud/bulk-delete/IN_PROGRESS',
} as const;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actions should be closer to user triggered events, not just generic actions

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated these names, how does it look now?

@gribnoysup gribnoysup Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming is only part of the problem here, the "close" action is still just a setter basically, it's not an "event" that happens in the app that causes the state change eventually, we should aim for having a clear separation between those because ultimately the goal is to have a clear log of actual events happening in the app. If you have a generic "close" action both for start of the delete and for user just closing the modal, you completely lose this distinction. This is the important conceptual difference that we should really try to capture in the code even if it feels redundant to have the same reducer logic for two different actions. Same applies to the update slice

@gribnoysup gribnoysup Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again want to point out this doc https://redux.js.org/style-guide#model-actions-as-events-not-setters and suggest to look closely at the detailed explanation, it's obviously exagerated, but the same thinking applies

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update some of the events here to not be setters used in multiple actions. Also updated it from having a status field in both update and delete to having an isOpen. Previously it would set the status to in-progress when a user started the bulk action and never update it until they opened it again. Let me know if there are more spots you see us using setters here, or actions we could improve.

import { refreshDocuments } from './documents';

export type BulkDeleteState = {
previews: Document[];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The line can be blurry sometimes, but we usually need a strong, good reason to store non-serializable instances like that in the store. Is there a good reason for it here? We serialize it at least once on open already, so why create instances here?

@Anemy Anemy Jul 11, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking, I got rid of the non-serializable documents here (now we store the ejson content of the docs, and useMemo to create the documents in the render). I also moved the abort controller off of the store for the bulk update.

Comment thread packages/compass-crud/src/stores/bulk-delete.ts Outdated
Comment thread packages/compass-crud/src/stores/bulk-delete.ts Outdated
Comment thread packages/compass-crud/src/stores/bulk-update.ts Outdated
Comment thread packages/compass-crud/src/stores/bulk-update.ts Outdated
@Anemy Anemy marked this pull request as ready for review July 11, 2026 00:03
@Anemy Anemy requested a review from a team as a code owner July 11, 2026 00:03
@Anemy Anemy requested a review from gribnoysup July 11, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants